import React from 'react';
import { forwardRef } from 'react';
import './index.scss';

export interface LayoutItem {
  id: string;
  component: React.ReactNode;
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  zIndex?: number;
  visible?: boolean;
  locked?: boolean;
  className?: string;
  style?: React.CSSProperties;
  componentName?: string; // 组件名称，用于低代码平台
  props?: any; // 组件属性
}

export interface LayoutContainerProps {
  width?: string | number;
  height?: string | number;
  layoutType?: 'absolute' | 'grid' | 'flex' | 'masonry';
  backgroundColor?: string;
  backgroundImage?: string;
  padding?: number | string;
  gap?: number;
  items?: LayoutItem[];
  
  // Grid布局配置
  gridColumns?: number;
  gridRows?: number;
  gridAutoFlow?: 'row' | 'column';
  
  // Flex布局配置
  flexDirection?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
  justifyContent?: 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
  alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
  flexWrap?: 'nowrap' | 'wrap' | 'wrap-reverse';
  
  // 交互配置
  allowDrag?: boolean;
  allowResize?: boolean;
  allowDrop?: boolean;
  showGrid?: boolean;
  gridSize?: number;
  snapToGrid?: boolean;
  acceptTypes?: string[]; // 接受的组件类型
  
  // 响应式配置
  responsive?: boolean;
  breakpoints?: {
    mobile?: number;
    tablet?: number;
    desktop?: number;
  };
  
  // 事件回调
  onItemMove?: (itemId: string, x: number, y: number) => void;
  onItemResize?: (itemId: string, width: number, height: number) => void;
  onItemSelect?: (itemId: string) => void;
  onItemAdd?: (item: LayoutItem) => void;
  onItemRemove?: (itemId: string) => void;
  onLayoutChange?: (items: LayoutItem[]) => void;
  onComponentDrop?: (componentData: any, position: { x: number; y: number }) => void;
  
  theme?: 'light' | 'dark';
  style?: React.CSSProperties;
  className?: string;
  onClick?: () => void;
  __designMode?: string;
  componentId?: string;
  _componentName?: string;
  forwardRef?: any;
}

const LayoutContainer = forwardRef<HTMLDivElement, LayoutContainerProps>((props, ref) => {
  const {
    width = '100%',
    height = '600px',
    layoutType = 'absolute',
    backgroundColor = 'transparent',
    backgroundImage,
    padding = 16,
    gap = 8,
    items = [
      {
        id: 'item1',
        component: <div className="demo-component">组件1</div>,
        x: 20,
        y: 20,
        width: 200,
        height: 100,
        zIndex: 1,
        visible: true
      },
      {
        id: 'item2',
        component: <div className="demo-component">组件2</div>,
        x: 240,
        y: 20,
        width: 200,
        height: 100,
        zIndex: 1,
        visible: true
      },
      {
        id: 'item3',
        component: <div className="demo-component">组件3</div>,
        x: 20,
        y: 140,
        width: 420,
        height: 80,
        zIndex: 1,
        visible: true
      }
    ],
    
    // Grid配置
    gridColumns = 3,
    gridRows = 'auto',
    gridAutoFlow = 'row',
    
    // Flex配置
    flexDirection = 'row',
    justifyContent = 'flex-start',
    alignItems = 'flex-start',
    flexWrap = 'wrap',
    
    // 交互配置
    allowDrag = false,
    allowResize = false,
    allowDrop = true,
    showGrid = false,
    gridSize = 10,
    snapToGrid = false,
    acceptTypes = ['*'], // 默认接受所有组件类型
    
    // 响应式配置
    responsive = true,
    breakpoints = {
      mobile: 768,
      tablet: 1024,
      desktop: 1200
    },
    
    // 事件回调
    onItemMove,
    onItemResize,
    onItemSelect,
    onItemAdd,
    onItemRemove,
    onLayoutChange,
    onComponentDrop,
    
    theme = 'dark',
    style = {},
    className = '',
    onClick,
    __designMode,
    componentId,
    _componentName,
    forwardRef: forwardRefProp,
    ...otherProps
  } = props;

  const [selectedItemId, setSelectedItemId] = React.useState<string | null>(null);
  const [dragState, setDragState] = React.useState<{
    isDragging: boolean;
    itemId: string | null;
    startX: number;
    startY: number;
    offsetX: number;
    offsetY: number;
  }>({
    isDragging: false,
    itemId: null,
    startX: 0,
    startY: 0,
    offsetX: 0,
    offsetY: 0
  });

  const [dropState, setDropState] = React.useState<{
    isDragOver: boolean;
    dropPosition: { x: number; y: number } | null;
  }>({
    isDragOver: false,
    dropPosition: null
  });

  const containerRef = React.useRef<HTMLDivElement>(null);

  const componentStyle: React.CSSProperties = {
    width: typeof width === 'number' ? `${width}px` : width,
    height: typeof height === 'number' ? `${height}px` : height,
    backgroundColor,
    backgroundImage: backgroundImage ? `url(${backgroundImage})` : undefined,
    padding: typeof padding === 'number' ? `${padding}px` : padding,
    gap: `${gap}px`,
    '--grid-size': `${gridSize}px`,
    '--grid-columns': gridColumns,
    '--grid-rows': typeof gridRows === 'number' ? gridRows : 'auto',
    '--flex-direction': flexDirection,
    '--justify-content': justifyContent,
    '--align-items': alignItems,
    '--flex-wrap': flexWrap,
    ...style
  } as React.CSSProperties;

  // 处理拖拽开始
  const handleMouseDown = (e: React.MouseEvent, itemId: string) => {
    if (!allowDrag) return;
    
    e.preventDefault();
    e.stopPropagation();
    
    const rect = containerRef.current?.getBoundingClientRect();
    if (!rect) return;
    
    const item = items.find(item => item.id === itemId);
    if (!item || item.locked) return;
    
    setDragState({
      isDragging: true,
      itemId,
      startX: e.clientX,
      startY: e.clientY,
      offsetX: e.clientX - rect.left - (item.x || 0),
      offsetY: e.clientY - rect.top - (item.y || 0)
    });
    
    setSelectedItemId(itemId);
    if (onItemSelect) {
      onItemSelect(itemId);
    }
  };

  // 处理拖拽移动
  const handleMouseMove = React.useCallback((e: MouseEvent) => {
    if (!dragState.isDragging || !dragState.itemId) return;
    
    const rect = containerRef.current?.getBoundingClientRect();
    if (!rect) return;
    
    let newX = e.clientX - rect.left - dragState.offsetX;
    let newY = e.clientY - rect.top - dragState.offsetY;
    
    // 对齐网格
    if (snapToGrid) {
      newX = Math.round(newX / gridSize) * gridSize;
      newY = Math.round(newY / gridSize) * gridSize;
    }
    
    // 边界限制
    const containerWidth = rect.width - (typeof padding === 'number' ? padding * 2 : 32);
    const containerHeight = rect.height - (typeof padding === 'number' ? padding * 2 : 32);
    const item = items.find(item => item.id === dragState.itemId);
    
    if (item) {
      newX = Math.max(0, Math.min(newX, containerWidth - (item.width || 100)));
      newY = Math.max(0, Math.min(newY, containerHeight - (item.height || 100)));
    }
    
    if (onItemMove) {
      onItemMove(dragState.itemId, newX, newY);
    }
  }, [dragState, onItemMove, snapToGrid, gridSize, padding]);

  // 处理拖拽结束
  const handleMouseUp = React.useCallback(() => {
    if (dragState.isDragging) {
      setDragState({
        isDragging: false,
        itemId: null,
        startX: 0,
        startY: 0,
        offsetX: 0,
        offsetY: 0
      });
    }
  }, [dragState.isDragging]);

  // 绑定全局鼠标事件
  React.useEffect(() => {
    if (dragState.isDragging) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      
      return () => {
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
      };
    }
  }, [dragState.isDragging, handleMouseMove, handleMouseUp]);

  // 处理项目点击选择
  const handleItemClick = (e: React.MouseEvent, itemId: string) => {
    e.stopPropagation();
    setSelectedItemId(itemId);
    if (onItemSelect) {
      onItemSelect(itemId);
    }
  };

  // 处理容器点击（取消选择）
  const handleContainerClick = (e: React.MouseEvent) => {
    if (e.target === e.currentTarget) {
      setSelectedItemId(null);
    }
    if (onClick) {
      onClick();
    }
  };

  // 处理拖拽进入
  const handleDragOver = React.useCallback((e: React.DragEvent) => {
    if (!allowDrop) return;
    
    e.preventDefault();
    e.stopPropagation();
    
    const rect = containerRef.current?.getBoundingClientRect();
    if (!rect) return;
    
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    
    setDropState({
      isDragOver: true,
      dropPosition: { x, y }
    });
  }, [allowDrop]);

  // 处理拖拽离开
  const handleDragLeave = React.useCallback((e: React.DragEvent) => {
    if (!allowDrop) return;
    
    // 只有当拖拽真正离开容器时才重置状态
    if (!containerRef.current?.contains(e.relatedTarget as Node)) {
      setDropState({
        isDragOver: false,
        dropPosition: null
      });
    }
  }, [allowDrop]);

  // 处理放置
  const handleDrop = React.useCallback((e: React.DragEvent) => {
    if (!allowDrop) return;
    
    e.preventDefault();
    e.stopPropagation();
    
    const rect = containerRef.current?.getBoundingClientRect();
    if (!rect) return;
    
    let x = e.clientX - rect.left - (typeof padding === 'number' ? padding : 16);
    let y = e.clientY - rect.top - (typeof padding === 'number' ? padding : 16);
    
    // 对齐网格
    if (snapToGrid) {
      x = Math.round(x / gridSize) * gridSize;
      y = Math.round(y / gridSize) * gridSize;
    }
    
    // 边界限制
    x = Math.max(0, x);
    y = Math.max(0, y);
    
    try {
      // 尝试解析拖拽数据
      const dragDataStr = e.dataTransfer.getData('text/plain');
      let componentData: any = {};
      
      if (dragDataStr) {
        try {
          componentData = JSON.parse(dragDataStr);
        } catch {
          // 如果不是JSON，当作普通文本处理
          componentData = {
            componentName: dragDataStr,
            type: 'text'
          };
        }
      }
      
      // 检查是否接受该组件类型
      if (acceptTypes && acceptTypes.length > 0 && !acceptTypes.includes('*')) {
        const componentType = componentData.componentName || componentData.type;
        if (!acceptTypes.includes(componentType)) {
          console.warn(`不接受的组件类型: ${componentType}`);
          return;
        }
      }
      
      // 创建新的布局项目
      const newItem: LayoutItem = {
        id: `item_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        component: componentData?.componentName || '新组件',
        componentName: componentData?.componentName,
        props: componentData?.props || {},
        x,
        y,
        width: componentData?.width || 200,
        height: componentData?.height || 100,
        zIndex: Math.max(...items.map(item => item.zIndex || 1), 1) + 1,
        visible: true,
        style: componentData?.style || {}
      };
      
      // 优先触发自定义组件放置事件
      if (onComponentDrop) {
        onComponentDrop(componentData, { x, y });
      }
      
      // 触发添加事件
      if (onItemAdd) {
        onItemAdd(newItem);
      }
      
      // 触发布局变化事件
      if (onLayoutChange) {
        const newItems = [...items, newItem];
        onLayoutChange(newItems);
      }
      
    } catch (error) {
      console.warn('处理拖放数据时出错:', error);
    }
    
    // 重置拖拽状态
    setDropState({
      isDragOver: false,
      dropPosition: null
    });
  }, [allowDrop, padding, snapToGrid, gridSize, acceptTypes, onComponentDrop, onItemAdd, onLayoutChange, items]);

  // 渲染网格背景
  const renderGridBackground = () => {
    if (!showGrid) return null;
    
    return (
      <div className="grid-background">
        <svg
          width="100%"
          height="100%"
          style={{ position: 'absolute', top: 0, left: 0, pointerEvents: 'none' }}
        >
          <defs>
            <pattern
              id="grid"
              width={gridSize}
              height={gridSize}
              patternUnits="userSpaceOnUse"
            >
              <path
                d={`M ${gridSize} 0 L 0 0 0 ${gridSize}`}
                fill="none"
                stroke="rgba(255,255,255,0.1)"
                strokeWidth="0.5"
              />
            </pattern>
          </defs>
          <rect width="100%" height="100%" fill="url(#grid)" />
        </svg>
      </div>
    );
  };

  // 渲染拖拽指示器
  const renderDropIndicator = () => {
    if (!dropState.isDragOver || !dropState.dropPosition) return null;
    
    return (
      <div 
        className="drop-indicator"
        style={{
          position: 'absolute',
          left: dropState.dropPosition.x - 10,
          top: dropState.dropPosition.y - 10,
          width: 20,
          height: 20,
          borderRadius: '50%',
          backgroundColor: '#1890ff',
          border: '2px solid white',
          boxShadow: '0 2px 8px rgba(24, 144, 255, 0.5)',
          zIndex: 1000,
          pointerEvents: 'none'
        }}
      />
    );
  };

  // 渲染布局项目
  const renderLayoutItems = () => {
    return items
      .filter(item => item.visible !== false)
      .map(item => {
        const itemStyle: React.CSSProperties = {
          ...item.style,
          zIndex: item.zIndex || 1
        };

        // 根据布局类型设置不同的定位方式
        if (layoutType === 'absolute') {
          itemStyle.position = 'absolute';
          itemStyle.left = `${item.x || 0}px`;
          itemStyle.top = `${item.y || 0}px`;
          itemStyle.width = item.width ? `${item.width}px` : 'auto';
          itemStyle.height = item.height ? `${item.height}px` : 'auto';
        }

        const isSelected = selectedItemId === item.id;
        const isDragging = dragState.isDragging && dragState.itemId === item.id;

        return (
          <div
            key={item.id}
            className={`layout-item ${item.className || ''} ${isSelected ? 'selected' : ''} ${isDragging ? 'dragging' : ''} ${item.locked ? 'locked' : ''}`}
            style={itemStyle}
            onMouseDown={(e) => handleMouseDown(e, item.id)}
            onClick={(e) => handleItemClick(e, item.id)}
            data-item-id={item.id}
            data-component-name={item.componentName}
          >
            {/* 选择指示器 */}
            {isSelected && allowDrag && !item.locked && (
              <div className="selection-indicator">
                {allowResize && (
                  <>
                    <div className="resize-handle resize-handle-nw" />
                    <div className="resize-handle resize-handle-ne" />
                    <div className="resize-handle resize-handle-sw" />
                    <div className="resize-handle resize-handle-se" />
                  </>
                )}
              </div>
            )}
            
            {/* 组件内容 */}
            <div className="layout-item-content">
              {item.component}
            </div>
          </div>
        );
      });
  };

  const layoutContainerClassName = [
    'layout-container',
    `layout-${layoutType}`,
    theme,
    responsive ? 'responsive' : '',
    allowDrag ? 'draggable' : '',
    allowDrop ? 'droppable' : '',
    dropState.isDragOver ? 'drag-over' : '',
    showGrid ? 'show-grid' : '',
    className
  ].filter(Boolean).join(' ');

  return (
    <div
      ref={(node) => {
        containerRef.current = node;
        if (typeof ref === 'function') {
          ref(node);
        } else if (ref) {
          ref.current = node;
        }
      }}
      className={layoutContainerClassName}
      style={componentStyle}
      onClick={handleContainerClick}
      onDragOver={handleDragOver}
      onDragLeave={handleDragLeave}
      onDrop={handleDrop}
      data-component-id={componentId}
      data-component-name={_componentName}
      data-design-mode={__designMode}
      data-accept-types={acceptTypes?.join(',')}
      {...otherProps}
    >
      {/* 网格背景 */}
      {renderGridBackground()}
      
      {/* 拖拽指示器 */}
      {renderDropIndicator()}
      
      {/* 布局项目 */}
      {renderLayoutItems()}
      
      {/* 拖拽提示 */}
      {allowDrop && dropState.isDragOver && (
        <div className="drop-hint">
          <span>松开鼠标放置组件</span>
        </div>
      )}
      
      {/* 调试信息 */}
      {__designMode && (
        <div className="debug-info">
          <span>布局: {layoutType}</span>
          <span>项目数: {items.filter(item => item.visible !== false).length}</span>
          {selectedItemId && <span>选中: {selectedItemId}</span>}
          {dropState.isDragOver && <span>拖拽中</span>}
        </div>
      )}
    </div>
  );
});

LayoutContainer.displayName = 'LayoutContainer';

export default LayoutContainer; 